/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.unisinos.tga;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.IntBuffer;
import javax.swing.JOptionPane;

/**
 *
 * @author Douglas
 */
public class Cenario {

    private Tileset tileSet = new Tileset();
    private int largura = 10;
    private int altura = 10;
    private int larguraImagem = 640;
    private int alturaImagem = 320;
    private String nome;
    public static final int TILE_H = 32;
    public static final int TILE_W = 64;
    private IsometricView isoView = null;
    private Imagem boneco = null;

    public Imagem getBoneco() {
        return boneco;
    }

    public void setBoneco(Imagem boneco) {
        this.boneco = boneco;
        linhaBoneco = 0;
        colunaBoneco = 0;
    }

    public int getLinhaBoneco() {
        return linhaBoneco;
    }

    public void setLinhaBoneco(int linhaBoneco) {
        this.linhaBoneco = linhaBoneco;
    }

    public int getColunaBoneco() {
        return colunaBoneco;
    }

    public void setColunaBoneco(int colunaBoneco) {
        this.colunaBoneco = colunaBoneco;
    }
    private int linhaBoneco = 0;
    private int colunaBoneco = 0;

    public Tileset getTileSet() {
        return tileSet;
    }

    public void setTileSet(Tileset tileSet) {
        this.tileSet = tileSet;
    }

    public int getLargura() {
        return largura;
    }

    public void setlargura(int tamanhoMap) {
        this.largura = tamanhoMap;
    }

    public int getAltura() {
        return altura;
    }

    public void setAltura(int altura) {
        this.altura = altura;
    }

    public IsometricView getIsoView() {
        return isoView;
    }

    public void setIsoView(IsometricView isoView) {
        this.isoView = isoView;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getLarguraImagem() {
        return larguraImagem;
    }

    public void setLarguraImagem(int larguraImagem) {
        this.larguraImagem = larguraImagem;
    }

    public int getAlturaImagem() {
        return alturaImagem;
    }

    public void setAlturaImagem(int alturaImagem) {
        this.alturaImagem = alturaImagem;
    }

    /**
     * Grava os dados do cenário em layout de arquivo específico por linha.
     * Ex:
     * nome;largura;altura;laguradaimage;alturadaimagem
     * dados do tilemap [linhaxcoluna]
     * dados do tileset [tamanho e número]
     * imagens do tileset em binário.
     * @param file 
     */
    public void salvarCenario(File file) {
        System.out.println(file.getName());
        try {
            file.delete();
            OutputStream save = new FileOutputStream(file);
            byte dados[] = (nome + ";" + largura + ";" + altura + ";" + larguraImagem + ";" + alturaImagem + "\n").getBytes();
            save.write(dados);

            for (int x = 0; x < altura; x++) {
                String s = "";
                for (int y = 0; y < largura; y++) {
                    s += getIsoView().tileMap.getTileId(x, y) + " ";
                }
                dados = (s + "\n").getBytes();
                save.write(dados);
            }
            String tileset = (this.tileSet.tileset.size() + " " + TILE_W + " " + TILE_H + "\n");
            dados = tileset.getBytes();
            save.write(dados);

            for (Tile tile : tileSet.tileset) {
                save.write((Integer.toString(tile.getId()) + "\n").getBytes());
                int count = 0;
                IntBuffer ib = tile.getImagem().getPixels();
                for (int i : ib.array()) {
//                    // considerando que deve ser opaco a=255
                    byte a = (byte) ((i >> 24) & 0xff);
                    byte r = (byte) ((i >> 16) & 0xff);
                    byte g = (byte) ((i >> 8) & 0xff);
                    byte b = (byte) (i & 0xff);
                    save.write(r);
                    count++;
                    save.write(g);
                    count++;
                    save.write(b);
//                    save.write(i);
                    count++;
                }
                save.write("\n".getBytes());
                System.out.println("Gravou " + count);
            }

            save.close();
            JOptionPane.showMessageDialog(null, "Arquivo '" + file.getName() + "' salvo com sucesso!");

        } catch (FileNotFoundException ex) {
            JOptionPane.showMessageDialog(null, "Caminho inválido para o arquivo!");
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Não foi possível criar o arquivo especificado!");
        }
    }

    /**
     * Carrega os dados do arquivo de cenário em formato específico
     * nome;largura;altura;laguradaimage;alturadaimagem
     * dados do tilemap [linhaxcoluna]
     * dados do tileset [tamanho e número]
     * imagens do tileset em binário.
     * @param file 
     */
    void carregarCenario(File file) {
        if (!file.exists()) {
            JOptionPane.showMessageDialog(null, "Arquivo inválido!");
        }
        try {
            InputStream read = new FileInputStream(file);

            String linha = Util.nextLine(read);
            String split[] = linha.split(";");

            nome = split[0];
            largura = Integer.parseInt(split[1]);
            altura = Integer.parseInt(split[2]);
            larguraImagem = Integer.parseInt(split[3]);
            alturaImagem = Integer.parseInt(split[4]);

            this.setIsoView(new IsometricView(largura, altura));

            for (int x = 0; x < altura; x++) {
                String s = Util.nextLine(read);
                String dados[] = s.split(" ");
                for (int y = 0; y < largura; y++) {
                    this.getIsoView().tileMap.setTileId(x, y, Integer.parseInt(dados[y]));
                }
            }
            // Lê a próxima linha, os dados dela não são necessários
            Util.nextLine(read);
            this.tileSet = new Tileset();
            Tile tile;
            Imagem imagem;

            while (!(linha = Util.nextLine(read)).equals("")) {
              
                imagem = new Imagem(TILE_W, TILE_H);
                tile = new Tile(0, null);
                // Canais de cor
                int r;
                int g;
                int b;
                int readByte = 0;
                int count = 0;
// Enquanto houver arquivo a ser lido
                while ((readByte = read.read()) != -1 && readByte != '\n') {
                    // Canal Red
                    r = readByte;
                    count++;
                    // Canal Green
                    g = read.read();
                    count++;
                    // Canal Blue
                    b = read.read();
                    count++;
                    imagem.setPixel(r, g, b);

//                    imagem.setPixel(readByte);
                    System.out.println(" " + readByte);
                }
                imagem.inverte();
                imagem.getPixels().rewind();
                System.out.println("Leu " + count);
                tile.setImagem(imagem);
                this.tileSet.addTile(tile, Integer.parseInt(linha));
                
            }
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Não foi possível ler o arquivo de cenário!");
        }
    }
}
